<template>
  <div>
    <a-button-group style="margin-bottom: 8px;">
      <a-button icon="plus" @click="handleAddMainTable" :disabled="dataSource.length > 0">{{$t('m.eform.apptable.other.er_add_mainTable')}}
      </a-button>
      <a-button v-if="objRelationVisible" icon="close" @click="handleShowObjRelation">{{$t('m.eform.apptable.other.er_close_objRelation')}}
      </a-button>
      <a-button v-else icon="search" @click="handleShowObjRelation">{{$t('m.eform.apptable.other.er_show_objRelation')}}
      </a-button>
    </a-button-group>

    <a-row v-show="objRelationVisible">
      <a-col :span="24">
        <a-textarea v-model="objRelationText" :rows="10" readOnly></a-textarea>
      </a-col>
    </a-row>

    <a-table
      bordered
      size="small"
      :title="title"
      rowKey="id"
      :columns="columns"
      :pagination="false"
      :expandedRowKeys="expandedRowKeys"
      @expand="handleExpand"
      :dataSource="dataSource">
          <span slot="action" slot-scope="text, record">
            <a @click="handleAddSubTable(record)">{{$t('m.eform.apptable.other.er_add_subTable')}}</a>
            <a-divider type="vertical"/>
            <a-popconfirm :title="$t('m.common.tip.delete_confirm')" @confirm="() => handleDelTable(record)">
              <a>{{ $t('m.common.button.delete') }}</a>
            </a-popconfirm>
          </span>
      <template slot="type" slot-scope="text, record">
        <ych-editable-cell v-if="visible && text !== 'main'" :text="text" type="select"
                       :select-data="selectTypeData"
                       @change="onCellChange(record, 'type', $event)"/>
        <span v-else-if="text === 'main'">
          {{$t('m.eform.apptable.other.er_mainTable')}}
        </span>
      </template>
      <template slot="fks" slot-scope="fkList, record">
        <fk-edit v-if="record.type !== 'main' && colTree[record.tableKey] && colTree[parentKey[record.id]]" :fkList="fkList" @change="selectFkChange"
                 :col-tree="colTree"
                 :sub-table="record.tableKey" :main-table="parentKey[record.id]"></fk-edit>
      </template>
    </a-table>

    <select-table-dialog ref="selectTableDialog" @selectFinished="selectTableOK"
                         :groupId="groupId"></select-table-dialog>
  </div>
</template>

<script>


  import { postAction } from '@/api/manage'
  import { EFormConstant } from '../../EFormConstant'
  import SelectTableDialog from '../../select/dialog/SelectTableDialog'
  import FkEdit from './FkEdit'
  import { delTableFromRelation, findAllKey } from '../EformUtils'
  import YchConstant from "@/api/YchConstant";
  import {YchEditableCell} from '@yuncheng/ych-components'
  import {randomString} from "../../../../utils/util";

  export default {
    name: 'ObjRelationTable',
    components: {
      SelectTableDialog,
      FkEdit,
      YchEditableCell
    },
    props: {
      objRelation: String,
      groupId: {
        type: String,
        required: true
      },
    },
    data () {
      return {
        title: () => {
          return this.$t('m.eform.apptable.other.er_objectRelation')
        },
        objRelationText: this.objRelation,
        dataSource: [],
        visible: false,
        current: null,
        currentType: null,
        expandedRowKeys: [],
        selectTypeData: EFormConstant.objStructure2,
        objRelationVisible: false,
        colTree: {},
        parentKey: {},
        columns: [
          {
            title: this.$t('m.eform.apptable.entity.tableName'),
            align: 'left',
            dataIndex: 'tableKey',
            customRender: function (t, r, index) {
              return r.tableComment + '(' + t + ')'
            }
          },
          {
            title: this.$t('m.eform.apptable.entity.er_type'),
            align: 'left',
            dataIndex: 'type',
            scopedSlots: { customRender: 'type' },
          },
          {
            title: this.$t('m.eform.apptable.entity.er_fks'),
            align: 'left',
            dataIndex: 'fks',
            scopedSlots: { customRender: 'fks' },
          },
          {
            title: this.$t('m.common.label.operate'),
            dataIndex: 'action',
            align: 'center',
            scopedSlots: { customRender: 'action' },
          }
        ],
        url: {
          getColTreeByBo: YchConstant.PREFIX_EFORM + '/manage/actAppObject/getColTreeByBo'
        }
      }
    },

    methods: {
      init(objRelation) {
        this.colTree = {}
        this.dataSource = []
        this.expandedRowKeys = []
        if (objRelation) {
          const json = JSON.parse(objRelation)
          this.addColTree(json).then(() => {
            this.dataSource = [json]
            this.initId(this.dataSource)
            this.expandedRowKeys = findAllKey(this.dataSource, "id")
            this.visible = true
          })
        } else {
          this.visible = true
        }
      },
      initId(dataSource, parentTable) {
        dataSource.forEach(item => {
          if (!item.id) {
            item.id = randomString(32)
          }
          if (item.children) {
            this.initId(item.children, item.tableKey)
          }
          this.parentKey[item.id] = parentTable
        })
      },
      handleAddMainTable () {
        this.current = null
        this.currentType = EFormConstant.objStructure_main
        this.$refs.selectTableDialog.radio = true
        this.$refs.selectTableDialog.visible = true
      },
      handleAddSubTable(record) {
        this.current = record
        this.currentType = EFormConstant.objStructure_oneToMany
        this.$refs.selectTableDialog.visible = true
      },
      selectTableOK(selectedRowKeys, selectionRows) {
        if (!selectionRows) {
          return
        }
        // 只查找直接下级的key
        // 在表单设计器中有重复表会有问题，先不允许有重复表
        // const allKeys = findAllKey(this.current ? this.current.children : this.dataSource, undefined, true)
        const allKeys = findAllKey(this.dataSource)
        let error = []
        for (let i = 0; i < selectionRows.length; i++) {
          this.addItems(selectionRows[i], allKeys, error)
        }
        if (error.length > 0) {
          this.messageUtil.warning(this.$t('m.eform.apptable.other.er_repeatTable') + JSON.stringify(error))
        }
      },
      addItems(row, allKeys, error) {
        const item = {
          id: randomString(32),
          tableComment: row.tableDesc,
          tableKey: row.tableName,
          type: this.currentType,
          children: [],
          fks: []
        }
        if (allKeys.indexOf(item.tableKey) !== -1) {
          error.push(item.tableKey + '/' + row.tableDesc)
          return
        }
        allKeys.push(item.tableKey)
        this.addColTree(item).then(() => {
          this.parentKey[item.id] = this.current ? this.current.tableKey : null
          const children = this.current ? this.current.children : this.dataSource
          children.push(item)
          this.expandedRowKeys.push(item.id)
          this.change()
        })
      },
      handleDelTable (record) {
        this.dataSource = delTableFromRelation(this.dataSource, record, "id")
        this.expandedRowKeys = findAllKey(this.dataSource, "id")
        this.change()
      },
      handleExpand (expanded, record) {
        if (expanded) {
          this.expandedRowKeys.push(record.id)
        } else {
          let keyIndex = this.expandedRowKeys.indexOf(record.id)
          if (keyIndex >= 0) {
            this.expandedRowKeys.splice(keyIndex, 1)
          }
        }
      },
      onCellChange (record, dataIndex, value) {
        record[dataIndex] = value
        this.change()
      },
      selectFkChange () {
        this.change()
      },
      change () {
        let json = ''
        if (this.dataSource.length > 0) {
          json = JSON.stringify(this.dataSource[0], null, 2)
        }
        this.$emit('change', json)
        this.objRelationText = json
      },
      addColTree (bo) {
        return new Promise((resolve,reject)=>{
          if (this.colTree[bo.tableKey]) {
            resolve()
            return
          }
          postAction(this.url.getColTreeByBo, bo).then((res) => {
            if (res.success) {
              this.colTree = Object.assign(this.colTree, res.result)
              resolve()
            } else {
              this.messageUtil.warning(res.message)
            }
          })
        })
      },
      handleShowObjRelation () {
        this.objRelationVisible = !this.objRelationVisible
      }
    },
    watch: {
      objRelation (value) {
        this.objRelationText = value
      }
    }
  }
</script>
